package io.dcloud.uniplugin.nfc;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.NfcV;
import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import io.dcloud.uniplugin.NFCModel;
import io.dcloud.uniplugin.listener.NFCListener;
import io.dcloud.uniplugin.tools.NfcVUtil;
import io.dcloud.uniplugin.tools.ThreadTools;


/**
 * 编辑 : yzhg
 * 时间 ：22:37-09-12 22:37
 * 包名 : com.benben.nfclib.nfc
 * 描述 : 一句话描述
 */
public class NFCInitTools {

    public static final String TAG = "NFCInitTools";

    private static List<String> blockData = new ArrayList<>();
    public static Boolean isDebug = false;

    /**
     * 检查NFC是否开启
     */
    public static NfcAdapter nfcCheck(Activity context, String language) {
        NfcAdapter mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
        if (mNfcAdapter == null) {
            if (!isDebug) {
                if (language != null && language.equals("zh")) {
                    NFCModel.invokeError("请检查并打开NFC");
                } else {
                    NFCModel.invokeError("Please check and turn on NFC");
                }
            }
        } else {
            if (!mNfcAdapter.isEnabled()) {
                if (!isDebug) {
                    if (language != null && language.equals("zh")) {
                        NFCModel.invokeError("NFC功能已经关闭，请前往设置页面打开");
                    } else {
                        NFCModel.invokeError("The NFC function has been turned off, please go to the settings page to turn it on");
                    }
                }
            }
        }
        return mNfcAdapter;
    }


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    /**
     * 读取TAG
     * @param factory 是否是工厂端
     *   工厂端直接写秘钥
     */
    public static void readTag(boolean factory, boolean isDefaultPassword, NfcAdapter mNfcAdapter, Intent intent, String language, NFCListener nfcListener) {
        //先进行秘钥校验
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
            Log.d(TAG, "action: TAG_DISCOVERED");
        }

        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            Log.d(TAG, "action: NDEF_DISCOVERED");
        }

        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            Log.d(TAG, "action: TECH_DISCOVERED");
        }


        //读取NFC数据
        if (!mNfcAdapter.isEnabled()) {
            if (language != null && language.equals("zh")) {
                NFCModel.invokeError("NFC功能已经关闭，请前往设置页面打开");
            } else {
                NFCModel.invokeError("The NFC function has been turned off, please go to the settings page to turn it on");
            }
            nfcListener.onReadError();
            return;
        }

        try {
            Tag tag = intent.<Tag>getParcelableExtra(NfcAdapter.EXTRA_TAG);
            //获取到id
            String nfcId = readNFCId(intent);
            if (nfcListener != null) {
                nfcListener.onReadId(nfcId);
            }
            Log.i(TAG, "=======读取到ID" + nfcId);

            if (TextUtils.isEmpty(nfcId) || nfcId.length() < 8) {
                if (!isDebug) {
                    if (language != null && language.equals("zh")) {
                        NFCModel.invokeError("读取失败,请检测NFC是否正常");
                    } else {
                        NFCModel.invokeError("If the reading fails, please check whether the NFC is normal");
                    }
                }
                if (nfcListener != null) {
                    nfcListener.onReadError();
                }
                return;
            }

            String[] techList = readNFCTechList(intent);
            if (nfcListener != null) {
                nfcListener.onReadSupportTech(techList);
            }
            if (Arrays.asList(techList).contains(NfcV.class.getName())) {
                Log.i(TAG, "support Ndef---tag:" + tag.toString());
                readNfcV(factory, isDefaultPassword, tag, nfcId, mNfcAdapter, intent, language, nfcListener);
            }
        } catch (Exception e) {
            Log.i(TAG, "读取失败:" + e.toString());
            if (!isDebug) {
                if (language != null && language.equals("zh")) {
                    NFCModel.invokeError("读取失败,请检测NFC是否正常");
                } else {
                    NFCModel.invokeError("If the reading fails, please check whether the NFC is normal");
                }
            }
            if (nfcListener != null) {
                nfcListener.onReadError();
            }
        }

    }


    /**
     * 读取NFCV中的数据 100153E0
     * @param factory 是否是工厂端
     */
    private static void readNfcV(boolean factory, boolean isDefaultPassword, Tag tag, String nfcId, NfcAdapter mNfcAdapter, Intent intent, String language, NFCListener nfcListener) {
        NfcV mNfcV = NfcV.get(tag);
        if (mNfcV != null) {
            clearFields();
            new Thread(() -> {
                try {
                    try {
                        mNfcV.close();
                    } catch (IOException e) {
                        if (!isDebug) {
                            if (language != null && language.equals("zh")) {
                                NFCModel.invokeError("读取失败,请检测NFC是否正常");
                            } else {
                                NFCModel.invokeError("If the reading fails, please check whether the NFC is normal");
                            }
                        }
                        nfcListener.onReadError();
                        return;
                    }
                    try {
                        mNfcV.connect();
                    } catch (IOException e) {
                        if (!isDebug) {
                            if (language != null && language.equals("zh")) {
                                NFCModel.invokeError("读取失败,请检测NFC是否正常");
                            } else {
                                NFCModel.invokeError("If the reading fails, please check whether the NFC is normal");
                            }
                        }
                        nfcListener.onReadError();
                        return;
                    }
                    NfcVUtil mNfcVutil = new NfcVUtil(mNfcV);
                    //如果是工厂端 先去写秘钥
                    //获取最新的秘钥
                    blockData = new ArrayList<>();
                    int blockIndex = 0;
                    for (int i = 0; i < 32; i++) {
                        String data = mNfcVutil.readOneBlock(i);
                        blockData.add(data);
                    }
                    //工厂端去修改秘钥
                    nfcListener.onReadBlocks(blockData);
                    try {
                        mNfcV.close();
                    } catch (IOException e) {
                        if (!isDebug) {
                            if (language != null && language.equals("zh")) {
                                NFCModel.invokeError("读取失败,请重新尝试");
                            } else {
                                NFCModel.invokeError("Read failed, please try again");
                            }
                        }
                        nfcListener.onReadError();
                    }

                } catch (Exception e) {
                    Log.i(TAG, "读取失败:" + e.toString());
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("读取失败,NFC距离过远");
                        } else {
                            NFCModel.invokeError("The read failed, and the NFC distance was too far");
                        }
                    }
                    nfcListener.onReadError();
                }
            }).start();
        }
    }

    /**
     * 校验秘钥
     */
    public static void setPsw(byte[] password, Intent intent, NfcAdapter mNfcAdapter, String language, NFCListener nfcListener) {
        NfcV nfcV = checkNfc(intent, mNfcAdapter);
        ThreadTools.runOnSubThread(() -> {
            try {
                try {
                    nfcV.close();
                } catch (IOException e) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("秘钥错误");
                        } else {
                            NFCModel.invokeError("The key is incorrect");
                        }
                    }
                    nfcListener.checkPassword(false);
                }
                try {
                    nfcV.connect();
                } catch (IOException e) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("秘钥错误");
                        } else {
                            NFCModel.invokeError("The key is incorrect");
                        }
                    }
                    nfcListener.checkPassword(false);
                }
                NfcVUtil nfcVUtil = new NfcVUtil(nfcV);
                boolean b = nfcVUtil.setPsw(nfcVUtil.getRand(), password);
                ThreadTools.runOnMainThread(() -> nfcListener.checkPassword(b));
            } catch (Exception e) {
                ThreadTools.runOnMainThread(() -> nfcListener.checkPassword(false));
            }
        });
    }


    /**
     * 写入密码
     * @param password 秘钥
     */
    public static void writePsw(byte[] password, byte[] oldPassword, Intent intent, NfcAdapter mNfcAdapter, String language, NFCListener nfcListener) {
        NfcV nfcV = checkNfc(intent, mNfcAdapter);
        ThreadTools.runOnSubThread(() -> {
            try {
                try {
                    nfcV.close();
                } catch (IOException e) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("开始失败");
                        } else {
                            NFCModel.invokeError("Start to fail");
                        }
                    }
                    nfcListener.writePswError();
                }
                try {
                    nfcV.connect();
                } catch (IOException e) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("开始失败");
                        } else {
                            NFCModel.invokeError("Start to fail");
                        }
                    }
                    nfcListener.writePswError();
                }
                NfcVUtil nfcVUtil = new NfcVUtil(nfcV);
                //第一步：校验秘钥
                boolean checkPassword = nfcVUtil.setPsw(nfcVUtil.getRand(), oldPassword);
                if (!checkPassword) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("秘钥错误");
                        } else {
                            NFCModel.invokeError("The key is incorrect");
                        }
                    }
                    nfcListener.writePswError();
                }
                Log.i(TAG, "writePsw: 秘钥校验结果" + checkPassword);
                //第二步：开启秘钥保护
                boolean protectPage = nfcVUtil.protectPage();
                if (!protectPage) {
                    if (!isDebug) {
                        if (language != null && language.equals("zh")) {
                            NFCModel.invokeError("秘钥错误");
                        } else {
                            NFCModel.invokeError("The key is incorrect");
                        }
                    }
                    nfcListener.writePswError();
                }
                Log.i(TAG, "writePsw: 开启秘钥保护结果" + protectPage);
                //第三步：修改秘钥
                boolean b = nfcVUtil.writePsw(password);
                Log.i(TAG, "writePsw: 修改秘钥结果" + b);
                ThreadTools.runOnMainThread(() -> nfcListener.writePswSuccess(b));
            } catch (Exception e) {
                ThreadTools.runOnMainThread(() -> nfcListener.writePswSuccess(false));
            }
        });
    }


    /**
     * 判断NFC模块是否可用
     */
    public static NfcV checkNfc(Intent intent, NfcAdapter mNfcAdapter) {
        if (mNfcAdapter == null) {
            return null;
        }
        if (!mNfcAdapter.isEnabled()) {
            return null;
        }

        Tag tag = intent.<Tag>getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (tag == null) {
            return null;
        }
        return NfcV.get(tag);
    }

    /**
     * 写入NFCV中的数据
     */
    public static void writeTag2(byte[] array, int position, Intent intent, NfcAdapter mNfcAdapter, String language, String checkTagId, String checkModel, NFCListener nfcListener) {
        if (mNfcAdapter == null) {
            if (!isDebug) {
                if (language != null && language.equals("zh")) {
                    NFCModel.invokeError("写入失败,请检查nfc是否连接");
                } else {
                    NFCModel.invokeError("If the write fails, check whether the NFC is connected");
                }
            }
            nfcListener.onReadError();
            return;
        }
        if (mNfcAdapter.isEnabled()) {
            Tag tag = intent.<Tag>getParcelableExtra(NfcAdapter.EXTRA_TAG);

            if (tag == null) {
                if (!isDebug) {
                    if (language != null && language.equals("zh")) {
                        NFCModel.invokeError("开始失败");
                    } else {
                        NFCModel.invokeError("Start to fail");
                    }
                }
                nfcListener.onReadError();
                return;
            }
            NfcV nfcv = NfcV.get(tag);


            if (nfcv != null) {
                new Thread(() -> {
                    try {
                        try {
                            nfcv.close();
                        } catch (IOException e) {
                            if (!isDebug) {
                                if (language != null && language.equals("zh")) {
                                    NFCModel.invokeError("开始失败");
                                } else {
                                    NFCModel.invokeError("Start to fail");
                                }
                            }
                            nfcListener.onReadError();
                        }
                        try {
                            nfcv.connect();
                        } catch (IOException e) {
                            if (!isDebug) {
                                if (language != null && language.equals("zh")) {
                                    NFCModel.invokeError("开始失败");
                                } else {
                                    NFCModel.invokeError("Start to fail");
                                }
                            }
                            nfcListener.onReadError();
                        }
                        //获取到id
                       // String tagId = readNFCId(intent);

                        NfcVUtil nfcVUtil = new NfcVUtil(nfcv);
                        //读取第28行校验位
                        String tagId12 = nfcVUtil.readOneBlock(12);
                        String tagId13 = nfcVUtil.readOneBlock(13);
                        String tagId14 = nfcVUtil.readOneBlock(14);
                        String tagId15 = nfcVUtil.readOneBlock(15);

                        List<String> tagList = new ArrayList<>();
                        tagList.add(tagId12);
                        tagList.add(tagId13);
                        tagList.add(tagId14);
                        tagList.add(tagId15);
                        String tagId = getTagId(tagList);
                        Log.i(TAG, "writeTag2: tagIdtagIdtagId"+tagId);
                        if (!tagId.equals(checkTagId)) {
                            if (language != null && language.equals("zh")) {
                                NFCModel.invokeError("设备id不匹配");
                            } else {
                                NFCModel.invokeError("The device id does not match");
                            }
                            nfcListener.onReadError();
                            return;
                        }

                        //读取第28行校验位
                        String module = nfcVUtil.readOneBlock(28);
                        if (!TextUtils.isEmpty(module)) {
                            String substring = module.substring(0, 4);
                            if (!substring.equals(checkModel)) {
                                if (language != null && language.equals("zh")) {
                                    NFCModel.invokeError("设备型号不匹配");
                                } else {
                                    NFCModel.invokeError("The device model does not match");
                                }
                                nfcListener.onReadError();
                                return;
                            }
                        }
                        boolean b = nfcVUtil.writeBlock(position, array);
                        ThreadTools.runOnMainThread(() -> {
                            nfcListener.writeSuccess(b);
                        });

                    } catch (Exception e) {
                        ThreadTools.runOnMainThread(() -> {
                            nfcListener.writeSuccess(false);
                        });
                    }
                }).start();
            } else {
                if (!isDebug) {
                    if (language != null && language.equals("zh")) {
                        NFCModel.invokeError("开始失败");
                    } else {
                        NFCModel.invokeError("Start to fail");
                    }
                }
                nfcListener.onReadError();
            }
        } else {
            if (!isDebug) {
                if (language != null && language.equals("zh")) {
                    NFCModel.invokeError("开始失败");
                } else {
                    NFCModel.invokeError("Start to fail");
                }
            }
            nfcListener.onReadError();
        }

    }

    private static void clearFields() {
        if (blockData != null) {
            blockData.clear();
        }
    }

    /**
     * 读取NFC的id
     */
    private static String readNFCId(Intent intent) {
        Tag tag = intent.<Tag>getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String id = "";
        if (tag != null) {
            id = bytes2HexString(tag.getId());
        }
        return id;
    }


    /**
     * 读取NFC的 Tech数据
     */
    private static String[] readNFCTechList(Intent intent) {
        Tag tag = intent.<Tag>getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = new String[]{};
        if (tag != null) {
            techList = tag.getTechList();
        }
        return techList;
    }


    public static String bytes2HexString(byte[] b) {
        StringBuilder ret = new StringBuilder();
        for (byte value : b) {
            String hex = Integer.toHexString(value & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret.append(hex.toUpperCase());
        }
        return ret.toString();
    }


    public static String hexToAscii(String hex) {
        StringBuilder asciiString = new StringBuilder();
        // 按每两个字符分割字符串
        for (int i = 0; i < hex.length(); i += 2) {
            String str = hex.substring(i, i + 2);
            // 将 16 进制转为 10 进制，再转为字符
            asciiString.append((char) Integer.parseInt(str, 16));
        }
        return asciiString.toString();
    }

    public static int hexToDecimal(String hex) {
        return Integer.parseInt(hex, 16); // 使用parseInt方法
    }

    /**
     * 获取Tagid
     */
    private static String getTagId(List<String> array) {

        StringBuilder dd = new StringBuilder();
        for (int i = 0; i < array.size(); i++) {
            dd.append(array.get(i));
        }
        if (TextUtils.isEmpty(dd)) {
            return "";
        }
        return NFCInitTools.hexToAscii(dd.toString());
    }

}
